package com.sense.cloud.coreservice.sdk.auth.annotation;

import com.sense.cloud.coreservice.sdk.auth.annotation.assit.ClassPathScanHandler;
import com.sense.cloud.coreservice.sdk.auth.utils.SdkPropUtil;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CodeWithHandler {
  
  private static CodeWithHandler instance = new CodeWithHandler();
  
  public static CodeWithHandler getInstance() {
    return instance;
  }
  
  private Map<String, CodeWith> codeMap = new Hashtable<String, CodeWith>();
  
  /**
   * 
   * @param packages.
   */
  public void scanner(String... packages) {
    ClassPathScanHandler scanHandler = new ClassPathScanHandler();
    for (String pkg : packages) {
      Set<Class<?>> pkgAllCls = scanHandler.getPackageAllClasses(pkg, true);
      for (Class<?> packageClass : pkgAllCls) {
        Map<String, CodeWith> codeMapTmp = scannerMethod(packageClass);
        if (codeMapTmp.isEmpty()) {
          continue;
        }
        codeMap.putAll(codeMapTmp);
      }
    }
  }
  
  private Map<String, CodeWith> scannerMethod(Class<?> packageClass) {
    Map<String, CodeWith> versions = new HashMap<String, CodeWith>();
    Method[] declaredMethods = packageClass.getDeclaredMethods();
    
    for (Method declaredMethod : declaredMethods) {
      int modifiers = declaredMethod.getModifiers();
      
      if (Modifier.isPrivate(modifiers)) {
        continue;
      }
      
      CodeWith annotation = declaredMethod.getAnnotation(CodeWith.class);
      if (annotation == null) {
        continue;
      }
      
      String uri = annotation.uri();
      versions.put(uri, annotation);
    }
    return versions;
  }
  
  /**
   * 
   * @param uri.
   * @param accessKey.
   * @return bol.
   */
  public boolean checkUriCode(String uri, String accessKey) {
    CodeWith codewith = codeMap.get(uri);
    if (codewith != null) {
      String code = codewith.code();
      List<String> ss = SdkPropUtil.getAccesskeysFromCode(code);
      if (ss != null && ss.contains(accessKey)) {
        return true;
      }
    }
    return false;
  }
  
}
